<template>
  <div class="header">
    <el-input
      style="width: 300px"
      v-model="CIDRValue"
      placeholder="输入CIDR地址(IPv4)  例如:172.18.0.1/16"
    ></el-input>
    <span v-if="isWarn" class="warn">当前地址不合法</span>
    <el-button @click="handleCIDRValue(CIDRValue)">点击计算</el-button>
  </div>
  <div class="nya-copy" v-clipboard:copy="addrNum">
    <span>可用地址：{{ addrNum }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
  <div class="nya-copy">
    <span>子网掩码：{{ subnetMask }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
  <div class="nya-copy">
    <span>子网地址：{{ subnetAddress }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
  <div class="nya-copy">
    <span>起始IP地址：{{ startIPaddr }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
  <div class="nya-copy">
    <span>结束IP地址：{{ endIPaddr }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
  <div class="nya-copy">
    <span>广播地址：{{ Broaddr }}</span>
    <i class="iconfont icon-fuzhi" @click="handleCopy" title="点击复制结果"></i>
  </div>
</template>

<script setup>
import { reactive, toRefs } from "vue";

const data = reactive({
  CIDRValue: "",
  addrNum: 0,
  subnetMask: "",
  netID: "",
  startIPaddr: "",
  endIPaddr: "",
  Broaddr: "",
  subnetAddress: "",
  isWarn: false,
});

const {
  CIDRValue,
  addrNum,
  subnetMask,
  netID,
  subnetAddress,
  startIPaddr,
  endIPaddr,
  Broaddr,
  isWarn,
} = toRefs(data);

const handleCIDRValue = (val) => {
  // replace 并没有什么软用,只是为了方便用到他的一部分特性
  if (val === "")
    return ElMessage({
      showClose: true,
      message: "地址不能为空！",
      type: "error",
    });
  data.isWarn = true;
  console.log(data.isWarn);
  val.replace(
    /(^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$)/,
    (...args) => {
      // 效验值
      // IP 0 - 255
      // 网络ID位数 0 - 32
      if (
        Number(args[2]) > 255 ||
        Number(args[2]) < 0 ||
        Number(args[3]) > 255 ||
        Number(args[3]) < 0 ||
        Number(args[4]) > 255 ||
        Number(args[4]) < 0 ||
        Number(args[5]) > 255 ||
        Number(args[5]) < 0 ||
        Number(args[6]) > 32 ||
        Number(args[6]) < 1
      ) {
        return args[1];
      }

      /**
       * CIDR 解析
       *  */
      // 验证通过
      data.isWarn = false;

      // 子网掩码二进制
      let subnetMaskBin = "1".repeat(Number(args[6])).padEnd(32, "0");

      // 获取子网掩码
      let subnetMaskArr = [];
      for (let i = 0; i < 4; i++) {
        subnetMaskArr.push(parseInt(subnetMaskBin.substr(i * 8, 8), 2));
      }
      data.subnetMask = subnetMaskArr.join(".");

      //   子网地址
      let CIDRValue = data.CIDRValue.split(".");
      let subnetMask = data.subnetMask.split(".");
      let subnetAddress = [];
      for (let i = 0; i < 4; i++) {
        subnetAddress.push(parseInt(CIDRValue[i]) & parseInt(subnetMask[i]));
      }
      data.subnetAddress = subnetAddress.join(".");
      console.log(subnetAddress);
      // 获取网络ID 广播地址 可用地址
      //   let netIDArr = [];
      let BroaddrArr = [];
      let addrNum = 0;
      subnetMaskArr.forEach((val, key) => {
        // 网络ID
        // netIDArr.push(Number(args[key + 2]) & val);
        // 广播地址
        BroaddrArr.push(Number(args[key + 2]) | (255 ^ val));
        // 可用地址
        addrNum +=
          (BroaddrArr[key] - subnetAddress[key]) * Math.pow(256, 3 - key);
      });
      //   data.netID = netIDArr.join(".");
      data.Broaddr = BroaddrArr.join(".");
      data.addrNum = Math.abs(addrNum - 1);

      // 获取起始IP地址
      subnetAddress[3] = subnetAddress[3] + 1;
      data.startIPaddr = subnetAddress.join(".");

      // 获取结束IP地址
      BroaddrArr[3] = BroaddrArr[3] - 1;
      data.endIPaddr = BroaddrArr.join(".");
      return args[1];
    }
  );

  // 提示警告
  data.isWarn = false;
  return;
};

//复制事件
const handleCopy = () => {
  if (
    data.addrNum === 0 ||
    data.subnetMask === "" ||
    data.subnetAddress === "" ||
    data.startIPaddr === "" ||
    data.endIPaddr === "" ||
    data.Broaddr === ""
  )
    return ElMessage({
      showClose: true,
      message: "不能复制空内容！",
      type: "error",
    });
  ElMessage({
    showClose: true,
    message: "复制成功",
    type: "success",
  });
};
</script>

<style lang="less" scoped>
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  .warn {
    color: red;
  }
}
.nya-copy {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  background-color: aliceblue;
  height: 35px;
  //   width: 440px;
  line-height: 35px;
  min-width: 200px;
  margin: 15px 0px 15px 0px;
  .iconfont {
    margin-right: 8px;
  }
  span {
    margin-left: 5px;
  }
}
</style>
